import * as turf from "@turf/turf"
import * as Cesium from "cesium"
import _ from "lodash"

//  笛卡尔坐标转为经纬度[x,y],返回 [经度, 纬度]
export function cartesian3ToLonLat(position) {
  const cartographic = Cesium.Cartographic.fromCartesian(position)
  const lon = Cesium.Math.toDegrees(cartographic.longitude)
  const lat = Cesium.Math.toDegrees(cartographic.latitude)
  return [lon, lat]
}
// 笛卡尔坐标转为GeoJSON
export const changeCartesin3ToGeoJson = (catersian3Arr, geojsonType) => {
  if (catersian3Arr?.length) {
    const positionList = []
    catersian3Arr.forEach((item) => {
      let position = cartesian3ToLonLat(item)
      positionList.push(position)
    })
    let geojson = {}
    if (geojsonType === "polygon") {
      positionList.push(positionList[0])
      geojson = turf.polygon([positionList])
    } else if (geojsonType === "polyline") {
      geojson = turf.lineString(positionList)
    }
    return {
      geojson: geojson,
      positionLng: positionList,
    }
  }
}

//笛卡尔坐标转为经纬度和高度
export function cartesian3ToDegreesHeight(position) {
  let c = Cesium.Cartographic.fromCartesian(position)
  return [
    Cesium.Math.toDegrees(c.longitude),
    Cesium.Math.toDegrees(c.latitude),
    c.height,
  ]
}

// 多边形切割
export const polygonCut = (
  poly,
  line,
  tolerance = 0.0002,
  toleranceType = "kilometers"
) => {
  //验证输入
  if (poly.geometry === void 0 || poly.geometry.type !== "Polygon")
    throw "传入的必须为polygon"
  if (
    line.geometry === void 0 ||
    line.geometry.type.toLowerCase().indexOf("linestring") === -1
  )
    throw "传入的必须为linestring"
  if (line.geometry.type === "LineString") {
    if (
      //检查切割线的起终点是否在多边形外
      turf.booleanPointInPolygon(
        //turf.point()：将坐标点转换为GeoJSON Point格式
        turf.point(line.geometry.coordinates[0]),
        poly
      ) ||
      //turf.booleanPointInPolygon()：检查点是否在多边形内部
      turf.booleanPointInPolygon(
        turf.point(
          //获取线段的起终点坐标
          line.geometry.coordinates[line.geometry.coordinates.length - 1]
        ),
        poly
      )
    )
      throw "起点和终点必须在多边形之外"
  }
  //计算线与多边形的交点
  let lineIntersect = turf.lineIntersect(line, poly)
  // 将线段分解成点
  const lineExp = turf.explode(line)
  // 存储所有交点的数组
  for (let i = 0; i < lineExp.features.length - 1; i++) {
    lineIntersect.features.push(
      turf.point(lineExp.features[i].geometry.coordinates)
    )
  }
  // 创建切割线的缓冲区
  const lineBuffer = turf.buffer(line, tolerance, {
    units: toleranceType,
  })
  // 执行切割,计算多边形与缓冲区的差集
  const _body = turf.difference(poly, lineBuffer)

  // 处理切割后的片段
  let pieces = []
  if (_body.geometry.type === "Polygon") {
    pieces.push(turf.polygon(_body.geometry.coordinates))
  } else {
    _body.geometry.coordinates.forEach(function (a) {
      pieces.push(turf.polygon(a))
    })
  }

  // 为每个片段分配ID
  pieces.forEach((a, index) => {
    a.properties = Object.assign({}, poly.properties)
    a.properties.id += `-${index}`
  })
  // 返回切割后的所有片段
  return turf.featureCollection(pieces)
}
